
#ifndef __DATA_STORE_H
#define __DATA_STORE_H

#include "Actor.h"
#include "../aprtools/APRTable.h"
#include "../db/KeyDB.h"
#include "../net/BrokerMessage.h"

/** A specialist actor class for collecting methods involving data
 * store manipulation. */
class DataStore : public Actor
{
   public:
      /** Data store state/error indicators. */
      enum datastorestate  { STORE_CREATED                     = 0x00,
                             ALREADY_EXISTS                    = 0x01,
                             STORE_ACCESS_DENIED               = 0x02,
                             ERROR_PARSING_SIZES               = 0x03,
                             ERROR_PARSING_HASHES              = 0x04,
                             ERROR_FINDING_USER                = 0x05,
                             NOT_ENOUGH_QUOTA                  = 0x06,
                             DATA_BLOCK_COMPLETE               = 0x07,
                             DATA_BLOCK_INCOMPLETE             = 0x08,
                             INVALID_PLAINTEXT_HASH_SPECIFIED  = 0x09,
                             WRONG_PLAINTEXT_HASH              = 0x0A,
                             INVALID_BLOCK_SIZE_SPECIFIED      = 0x0B,
                             MISMATCHED_BLOCK_SIZE             = 0x0C,
                             NO_ALLOCATED_SPACE                = 0x0D,
                             MESSAGE_CORRUPT                   = 0x0E,
                             HASHES_FILE_ERROR                 = 0x0F,
                             SIZES_FILE_ERROR                  = 0x10,
                             DATA_FILE_ERROR                   = 0x11,
                             BLOCK_ACCESS_DENIED               = 0x12,
                             TRANSFER_HASH_MISSING             = 0x13,
                             TRANSFER_HASH_MISMATCH            = 0x14,
                             TRANSFER_PAYLOAD_NUMBER_NOT_FOUND = 0x15,
                             TRANSFER_PAYLOAD_NOT_FOUND        = 0x16,
                             DATA_FILE_UNMOVED                 = 0x17,
                             FILE_CREATION_FAILED              = 0x18,
                             FILE_CREATION_SUCCEEDED           = 0x19,
                             ACTOR_CREATION_SUCCEEDED          = 0x1A,
                             TRANSFER_SUCCEEDED                = 0x1B  };
      DataStore(ActorsDB *adb, const char *iname, const char *iowner);
      virtual ~DataStore();
      datastorestate startNew(BrokerMessage &msgin, KeyDB *keydb, const char *decryptingkeyname, apr_pool_t *t_mp);
      datastorestate checkBlockStatus(const APRTable *headertable, apr_pool_t *t_mp);
      datastorestate writeBlock(BrokerMessage &msgin, apr_pool_t *t_mp);
      datastorestate readBlock(BrokerMessage &msgout, int blockid, apr_pool_t *t_mp);
      void writeOutStatus(BrokerMessage &msgout, apr_pool_t *t_mp);
      static const char *stateToMessageTag(datastorestate tstate);
      static const char *stateToErrorMessage(datastorestate tstate);
   protected:
      void rollbackDataStoreActor(const char *actorname, KeyDB *keydb);
      void rollbackNewStoreFiles(const char *size_str, const char *hashes_str, const char *ult_user, apr_pool_t *t_mp);
      datastorestate createNewDataStoreActor(BrokerMessage &msgin, const char *ult_user,
         int tblocksize, int no_of_blocks, apr_pool_t *t_mp, KeyDB *nkdb, const char *decryptingkeyname);
      datastorestate createNewStoreFiles(const char *size_str, const char *hashes_str, const char *ult_user, apr_pool_t *t_mp);
      datastorestate checkFileBlockStatus(const int blockid, const char *plainhash, const apr_size_t datasize, apr_pool_t *t_mp);
   private:
      /** The ID of the data store (name). */
      char *data_store_id;
      /** Does this data store exist? (has it been created?) */
      int existing;
      /** Is the data store invalid? (and possibly need to be
       * destroyed?) */
      int invalid;
};

#endif
